/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author xxxcsg
 * @brief 系统硬件信息工具函数库
 * @details 提供 OpenHarmony 系统核心硬件信息的采集函数，专注于架构、内存、存储资源的数据获取，核心功能如下：
 *          1. get_arch：通过 uname -m 命令获取 CPU 架构信息（如 aarch64），自动去除换行符并返回动态分配的字符串
 *          2. get_memory：读取 /proc/meminfo 文件，解析总内存（MemTotal）和空闲内存（MemFree），转换为 MB 单位后通过指针输出
 *          3. get_storage_root：通过 statvfs 函数获取 / 根分区的空闲存储空间，转换为 MB 单位返回
 *          4. get_storage_userdata：通过 statvfs 函数获取 /userdata 分区的空闲存储空间，转换为 MB 单位返回
 * @note 1. 依赖组件：标准 C 库（文件操作、进程调用、字符串处理）、sys/statvfs.h（存储信息获取）
 *       2. 单位说明：所有内存和存储信息均以 MB 为单位输出，便于上层模块统一处理和展示
 *       3. 内存分配：get_arch 函数返回的字符串通过 strdup 动态分配，调用者需手动 free 释放，避免内存泄漏
 *       4. 容错处理：文件打开失败或命令执行失败时，返回默认值（架构返回 "unknown"，内存/存储返回 0）
 * @attention 1. 权限要求：需确保程序具备 /proc/meminfo 文件的读取权限，以及 uname 命令的执行权限
 *            2. 路径依赖：/userdata 分区路径固定，若目标设备存储分区布局不同，需调整 get_storage_userdata 中的路径参数
 *            3. 指针安全：get_memory 函数要求输入的 total 和 free 指针非空，否则可能导致未定义行为
 *            4. 动态内存：调用 get_arch 后必须释放返回的字符串，否则会造成内存泄漏
 */
#include "sysphutil.h"


// 获取处理器架构
char* get_arch() {
    char buffer[128];
    FILE* pipe = popen("uname -m", "r");
    if (!pipe) return "unknown";
    fgets(buffer, sizeof(buffer), pipe);
    pclose(pipe);

    // 去掉换行符
    size_t len = strlen(buffer);
    if (len > 0 && buffer[len-1] == '\n') {
        buffer[len-1] = '\0';
    }

    return strdup(buffer);
}

// 获取内存信息（MB）
void get_memory(unsigned long* total, unsigned long* free) {
    FILE* meminfo = fopen("/proc/meminfo", "r");
    if (meminfo) {
        char line[256];
        while (fgets(line, sizeof(line), meminfo)) {
            if (strstr(line, "MemTotal")) sscanf(line, "MemTotal: %lu kB", total);
            if (strstr(line, "MemFree")) sscanf(line, "MemFree: %lu kB", free);
        }
        *total /= 1024; // 转换为MB
        *free /= 1024;
        fclose(meminfo);
    }
}

// 获取存储空间（MB）
unsigned long get_storage_root() {
    struct statvfs vfs;
    if (statvfs("/", &vfs) == 0) {
        return (vfs.f_bsize * vfs.f_bavail) / (1024 * 1024);
    }
    return 0;
}

// 获取存储空间（MB）
unsigned long get_storage_userdata() {
    struct statvfs vfs;
    if (statvfs("/userdata", &vfs) == 0) {
        return (vfs.f_bsize * vfs.f_bavail) / (1024 * 1024);
    }
    return 0;
}